﻿//---------------------------------------------------------------------
// Copyright (c) 2007 Digerati Technologies, LLC.  All Rights Reserved.
//
// Release under the Microsoft Public License (Ms-PL).
//---------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.Reflection;

namespace DigeratiTech.NDiagnostics
{
    /// <summary>
    /// Specifies the current status of a <see cref="DiagnosticTask"/>.
    /// </summary>
    public enum TaskStatus
    {
        /// <summary>
        /// The task is current waiting to be executed.
        /// </summary>
        [Description("Not Run")]
        NotRun,
        /// <summary>
        /// The task is currently running.
        /// </summary>
        [Description("Running")]
        Scanning,
        /// <summary>
        /// The task has successfully completed.
        /// </summary>
        [Description("Successful")]
        Completed,
        /// <summary>
        /// The task has completed in error.
        /// </summary>
        [Description("Error")]
        Error,
        /// <summary>
        /// The task has completed with a warning.
        /// </summary>
        [Description("Warning")]
        Warning
    }

    public abstract class DiagnosticTask
    {
        #region Private Attributes...

        private string _id = Guid.NewGuid().ToString().Replace("-", "");
        private string _description;
        private TaskStatus _status;

        #endregion

        #region Properties...

        /// <summary>
        /// Gets the task ID.
        /// </summary>
        /// <value>The task ID.</value>
        /// <remarks>The ID is a unique string, generated at run-time, associated with each task.</remarks>
        public string Id { get { return _id; } }

        /// <summary>
        /// Gets or sets the <see cref="TaskGroup"/> this task belongs to.
        /// </summary>
        /// <value>The <see cref="TaskGroup"/> this task belongs to.</value>
        public TaskGroup taskGroup { get; set;}

        /// <summary>
        /// Gets or sets the task name.
        /// </summary>
        /// <value>The task name.</value>
        public string Name { get; set;}

        /// <summary>
        /// Gets or sets the description to be associated with this task.
        /// </summary>
        /// <value>The description to be associated with this task.</value>
        public string Description
        {
            get
            {
                if (string.IsNullOrEmpty(_description))
                    return Name;
                else
                    return _description;
            }
            set
            {
                _description = value;
            }
        }

        /// <summary>
        /// Gets or sets the current task status.
        /// </summary>
        /// <value>The current task status.</value>
        public TaskStatus Status
        {
            get
            {
                return _status;
            }
            set
            {
                _status = value;

                if ((_status == TaskStatus.Error) && (FailAsWarning))
                {
                    _status = TaskStatus.Warning;
                }
            }
        }

        /// <summary>
        /// Gets the status text.
        /// </summary>
        /// <value>The status text.</value>
        public string StatusText
        {
            get
            {
                FieldInfo fieldInfo = Status.GetType().GetField(Status.ToString());
                DescriptionAttribute[] attributes =(DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

                return (attributes.Length > 0) ? attributes[0].Description : Status.ToString();
            }
        }

        /// <summary>
        /// Gets or sets the message associated with this task.
        /// </summary>
        /// <value>The message associated with this task.</value>
        public string Message { get; set; }

        /// <summary>
        /// Gets or sets a flag indicating whether a failure should be treated as a warning.
        /// </summary>
        public bool FailAsWarning { get; set; }

        #endregion

        #region Constructors...

        /// <summary>
        /// Initializes a new instance of the <see cref="DiagnosticTask"/> class.
        /// </summary>
        public DiagnosticTask()
        {
            taskGroup = null;
            Name = "Undefined Name";
            Status = TaskStatus.Error;
            Message = string.Empty;
        }

        #endregion

        #region Methods...

        /// <summary>
        /// Executes the task.
        /// </summary>
        /// <returns><c>true</c> if the task is successful; otherwise, <c>false</c>.</returns>
        public virtual bool Execute()
        {
            return false;
        }

        #endregion
    }
}
